﻿#pragma once

#include "Common/DeviceResources12.h"
#include "Common/StepTimer.h"


// A basic game implementation that creates a D3D12 device and
// provides a game loop.
class GameD12UW final : public DX::IDeviceNotify//, MyMouse::Impl, Keyboard::Impl
{
public:

	GameD12UW() noexcept(false);

	void SetWindow(CoreWindow^ window);

	void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);

	// Initialization and management
	void Initialize(CoreWindow^ window, int width, int height, DXGI_MODE_ROTATION rotation);

	// Basic render loop
	void Tick();

	// IDeviceNotify
	virtual void OnDeviceLost() override;
	virtual void OnDeviceRestored() override;

	// Messages
	void OnActivated();
	void OnDeactivated();
	void OnSuspending();
	void OnResuming();
	void OnWindowSizeChanged(int width, int height, DXGI_MODE_ROTATION rotation);
	void ValidateDevice();
	void NewAudioDevice();

	// Properties
	void GetDefaultSize(int& width, int& height) const;

private:

	void Update(DX::StepTimer const& timer);
	void Render();

	void Clear();

	void CreateDeviceDependentResources();
	void CreateWindowSizeDependentResources();

	void XM_CALLCONV DrawGrid(DirectX::FXMVECTOR xAxis, DirectX::FXMVECTOR yAxis, DirectX::FXMVECTOR origin, size_t xdivs, size_t ydivs, DirectX::GXMVECTOR color);

	// Device resources.
	std::unique_ptr<DX::DeviceResources12>        m_deviceResources;

	// Rendering loop timer.
	DX::StepTimer                               m_timer;

	// Input devices.
	std::unique_ptr<DirectX::GamePad>           m_gamePad;
	std::unique_ptr<DirectX::Keyboard>          m_keyboard;
	std::unique_ptr<DirectX::Mouse>             m_mouse;

	DirectX::GamePad::ButtonStateTracker        m_gamePadButtons;
	DirectX::Keyboard::KeyboardStateTracker     m_keyboardButtons;

	// DirectXTK objects.
	std::unique_ptr<DirectX::GraphicsMemory>                                m_graphicsMemory;
	std::unique_ptr<DirectX::DescriptorHeap>                                m_resourceDescriptors;
	std::unique_ptr<DirectX::CommonStates>                                  m_states;
	std::unique_ptr<DirectX::BasicEffect>                                   m_lineEffect;
	std::unique_ptr<DirectX::PrimitiveBatch<DirectX::VertexPositionColor>>  m_batch;
	std::unique_ptr<DirectX::BasicEffect>                                   m_shapeEffect;
	std::unique_ptr<DirectX::Model>                                         m_model;
	std::vector<std::shared_ptr<DirectX::IEffect>>                          m_modelEffects;
	std::unique_ptr<DirectX::EffectTextureFactory>                          m_modelResources;
	std::unique_ptr<DirectX::GeometricPrimitive>                            m_shape;
	std::unique_ptr<DirectX::SpriteBatch>                                   m_sprites;
	std::unique_ptr<DirectX::SpriteFont>                                    m_font;

	std::unique_ptr<DirectX::AudioEngine>                                   m_audEngine;
	std::unique_ptr<DirectX::WaveBank>                                      m_waveBank;
	std::unique_ptr<DirectX::SoundEffect>                                   m_soundEffect;
	std::unique_ptr<DirectX::SoundEffectInstance>                           m_effect1;
	std::unique_ptr<DirectX::SoundEffectInstance>                           m_effect2;

	Microsoft::WRL::ComPtr<ID3D12Resource>                                  m_texture1;
	Microsoft::WRL::ComPtr<ID3D12Resource>                                  m_texture2;

	uint32_t                                                                m_audioEvent;
	float                                                                   m_audioTimerAcc;

	bool                                                                    m_retryDefault;

	DirectX::SimpleMath::Matrix                                             m_world;
	DirectX::SimpleMath::Matrix                                             m_view;
	DirectX::SimpleMath::Matrix                                             m_projection;

	// Descriptors
	enum Descriptors
	{
		WindowsLogo,
		SeaFloor,
		SegoeFont,
		Count = 256
	};
};